<?php

namespace app\api\controller;

use think\Controller;
use think\Request;
use think\Db;
use app\common\service\BiaotabService;
use DB as GlobalDB;

class Table extends Controller
{

    // 从ocr表中获取数据，并插入到hmc表中
    public function index()
    {
        $qzh="NJ03";

        $map['qzh']=array("=",$qzh);
        $keyword="花名册";
        $map['tm']=array("like","%".$keyword."%");
        $map['ocr_status']=array("=",1);
        $map['is_delete']=array("=",0);

        $data=DB::name('zstp_article_ocr')->where($map)->select();

        $insert_data=[];
        

        foreach($data as $key=>$value){
           $arr=array(
            "atricle_id"=>$value['id'],
            "tm"=>$value['tm'],
           );
           $insert_data[]=$arr;
        }

        Db::name('zstp_hmc')->insertAll($insert_data);

    }


    // 处理cor h花名册
    public function hmc()
    {
        
        $map['status']=array("=",0);
        


        $data=Db::table('zstp_hmc')->where($map)->find();
        var_dump($data);


        $ocrMap['id']=array("=",$data['atricle_id']);

        $ocrData=Db::table('zstp_article_ocr')->field('tm,dh,qzh,bgqx,lbh,ajh,jh,task_id')->where($ocrMap)->find();
        $dh=$ocrData['dh'];
        $qzh=$ocrData['qzh'];
        $jh=$ocrData['jh'];
        //查文件夹地址

        $taskMap['id']=array("=",$ocrData['task_id']);

        $taskData=Db::table('zstp_article_task')->field('path')->where($taskMap)->find();


        $folder= $ocrData['bgqx']."WS.WS".$ocrData['lbh'].$ocrData['ajh'];

        $filePath=$taskData['path']."/".$folder;


        
        $items=$this->myScandir($filePath);


        $groupedFiles = $this->fileGroup($items);


        $fileItems=$groupedFiles[$jh];
        //转成json
        $fileItems=json_encode($fileItems);
        $dataMk['new_document_path']= $filePath;
        $dataMk['file_path']= $fileItems;
        $biaotabService=new BiaotabService();
        $res=  $biaotabService->index($dataMk);

        if(empty($res['data'])){
            return json(array(
                "code"=>400,
                "msg" =>"没有表单数据"
            ));
        }

        $list=$res['data'];

        $dataInsertAll=[];

        foreach($list as $key=>$value){
            if(empty($value)){
                continue;
            }

            $dataInsertAll[]=[
                "qzh"=>$qzh,
                "dh"=>$dh,
                "text"=>$value,
            ];
        }

        Db::table('zstp_queue_mk')->insertAll($dataInsertAll);
  
    }

    // 大模型解析花名册
    public function dmk()
    {
        $map['status']=array("=",0);

        $data=Db::table('zstp_queue_mk')->where($map)->find();

        $id=$data['id'];

        Db::table("zstp_queue_mk")->where("id",$id)->update(array('status'=>2));

        $data=  $this->mk($data);
      
        var_dump($data);


        if(!empty( $data['data'])){
            
            Db::connect(config("db_config"))->table('zstp_neo4j_personal_attributes')->insertAll($data['data']);
        }
        
        Db::table("zstp_queue_mk")->where("id",$id)->update(array('status'=>1));

    }

    public function mk($data){

 

        $dh=$data['dh'];

        $qzh=$data['qzh'];

        $map['dh']=$dh;
        $map['zstp_is_delete']= 0;

        //查文件编号
        $fileResult = Db::connect(config("db_config"))->table('zstp_article')->field('id,wjbh')->where( $map)->find();

   
        if(empty($fileResult)){
            return ['code' => 400, 'msg' => '文件不存在' ,'data'=>[]];
        }   
        $wjbh=$fileResult['wjbh'];
        $article_id=$fileResult['id'];
        $queue_id=$data['id'];



        $cueWord = '请严格按照以下json格式输出。请注意不能多字段,也不能少字段，如果字段值未知，则直接输出""，请严格按照样例格式输出数据，从我给你的文章中提取奖惩相关的信息填入对应的json字段中，注意所有信息必须在原文中有说体现，不能凭空捏造，同时，你只需要输出json格式的数据，不要附带有说明性质的文字,name无法确认，就不要输出记录：
 [
    {
      "name": "string", // 名字
      "gender": "string", // 性别
      "ethnicity": "string", // 名族
      "political_status":"string",//政治面貌
      "marital_status": "string", // 婚姻状态
      "marriage_date":"YYYY-MM-DD", //结婚日期
      "birth_date":"YYYY-MM-DD", //出生日期
      "party_join_date":"YYYY-MM-DD", //入党时间
      "enlistment_date":"YYYY-MM-DD", //入伍时间
      "discharge_date":"YYYY-MM-DD", //退伍时间
      "occupation": "string", // 职业
      "native_place":"string", //籍贯
      "education":"string", //学历
      "graduation_institution":"string", //毕业院校
      "skills_and_expertise":"string"//专业技能及特长
    }
]

示例验证：
输入文本：
"| 人名     | 性别 | 名族 | 政治面貌   | 婚姻状态 | 结婚日期   | 出生日期    | 入党时间    | 入伍时间 | 退伍时间 | 职业               | 籍贯     | 学历 | 毕业院校   | 专业技能及特长             |
|----------|------|------|------------|----------|------------|-------------|-------------|----------|----------|--------------------|----------|------|------------|--------------------------|
| 李剑彤   | 男   | 汉   | 中共党员   | 已婚     | 2008-05-20 | 1987-01-01  | 2010-07-01  |          |          | 项目经理 高工       | 山东济南 | 本科 | 山东大学   | 安全生产继续教育培训       |
| 唐君杰   | 男   | 汉   | 群众       | 未婚     |            | 1987-03-15  |             |          |          | 常务经理 工程师     | 江苏南京 | 硕士 | 东南大学   | 安全生产继续教育培训       |"
解析结果：
 [
        {
           
            "name": "李剑彤",
            "gender": "男",
            "ethnicity":"汉",
            "political_status":"中共党员",
            "marital_status":"已婚",
            "marriage_date":"2008-05-20",
            "birth_date":"1987-01-01",
            "party_join_date":"2010-07-01",
            "enlistment_date":"",
            "discharge_date":"",
            "occupation":"项目经理 高工",
            "native_place":"山东济南",
            "education":"本科",
            "graduation_institution":"山东大学",
            "skills_and_expertise":"安全生产继续教育培训"
        },

        {
            "name": "唐君杰",
            "gender": "男",
            "ethnicity":"汉",
            "political_status":"群众",
            "marital_status":"未婚",
            "marriage_date":"",
            "birth_date":"1987-03-15",
            "party_join_date":"",
            "enlistment_date":"",
            "discharge_date":"",
            "occupation":"常务经理 工程师",
            "native_place":"江苏南京",
            "education":"硕士",
            "graduation_institution":"东南大学",
            "skills_and_expertise":"安全生产继续教育培训"
            
        },
 ]
';
        $cueWord=$cueWord."
        "."markdownn 内容：
        ".$data['text'];

 
   
        $data= $this->ollamaMk($cueWord);

        $dataArr = json_decode($data, true);
        $content = $dataArr['message']['content'];

    
        $substring = mb_substr($content, 0, 7);
    
        if ($substring == "```json") {
            preg_match('/```json\s*([\s\S]*?)\s*```/', $content, $matches);
            $content = $matches[1];
        }

      
        $arr = json_decode($content, true);

 
        if(empty($arr)){
            return ['code' => 200, 'msg' => '解析失败' ,'data'=>[]];
        }


   

        $redata=[];

        foreach($arr as $key=>$value){

            $insert = [];
            $insert['article_id']=$article_id;
            $insert['queue_id']=$queue_id;
            $insert['wjbh']=$wjbh;
            $insert['qzh']=$qzh;
            $insert['dh']=$dh;
            $insert['type']='ocr_mk';
            $count = 0;
            if (empty($value['name']) || !checkFields($value['name'])) {
                continue;
            }
            $insert['name'] = $value['name'];

            $insert['gender'] = "";

            if (!empty($value['gender']) && checkFields($value['gender'])) {
                $insert['gender'] = $value['gender'];
                $count++;
            }
            $insert['ethnicity'] = "";
            if (!empty($value['ethnicity']) && checkFields($value['ethnicity'])) {
                $insert['ethnicity'] = $value['ethnicity'];
                $count++;
            }

            $insert['political_status'] = "";
            if (!empty($value['political_status']) && checkFields($value['political_status'])) {
                $insert['political_status'] = $value['political_status'];
                $count++;
            }

            $insert['marital_status'] = "";
            if (!empty($value['marital_status']) && checkFields($value['marital_status'])) {
                $insert['marital_status'] = $value['marital_status'];
                $count++;
            }
            $insert['birth_date'] = "";
            if (!empty($value['birth_date']) && checkFields($value['birth_date'])) {
                $insert['birth_date'] = $value['birth_date'];
                $count++;
            }
            $insert['party_join_date'] = "";
            if (!empty($value['party_join_date']) && checkFields($value['party_join_date'])) {
                $insert['party_join_date'] = $value['party_join_date'];
                $count++;
            }
            $insert['enlistment_date'] = "";
            if (!empty($value['enlistment_date']) && checkFields($value['enlistment_date'])) {
                $insert['enlistment_date'] = $value['enlistment_date'];
                $count++;
            }
            $insert['discharge_date'] = "";
            if (!empty($value['discharge_date']) && checkFields($value['discharge_date'])) {
                $insert['discharge_date'] = $value['discharge_date'];
                $count++;
            }
            $insert['native_place'] = "";
            if (!empty($value['native_place']) && checkFields($value['native_place'])) {
                $insert['native_place'] = $value['native_place'];
                $count++;
            }
            $insert['education'] = "";
            if (!empty($value['education']) && checkFields($value['education'])) {
                $insert['education'] = $value['education'];
                $count++;
            }

            $insert['graduation_institution'] = "";
            if (!empty($value['graduation_institution']) && checkFields($value['graduation_institution'])) {
                $insert['graduation_institution'] = $value['graduation_institution'];
                $count++;
            }
            $insert['skills_and_expertise'] = "";
            if (!empty($value['skills_and_expertise']) && checkFields($value['skills_and_expertise'])) {
                $insert['skills_and_expertise'] = $value['skills_and_expertise'];
                $count++;
            }
            $insert['occupation'] = "";
            if (!empty($value['occupation']) && checkFields($value['occupation'])) {
                $insert['occupation'] = $value['occupation'];
                $count++;
            }

            if($count>0){
                $redata[]=$insert;
            }


        }

        return   array("code"=>200,"data"=>$redata);

    
    }

        /**
     * 对文件进行分组
     * 
     * @param array $files 文件列表
     * @return array 分组后的文件
     */
    protected function fileGroup($files)
    {
        if (empty($files)) {
            return [];
        }

        // 初始化一个数组来存储分组结果
        $groupedFiles = [];

        // 遍历文件列表并进行分组
        foreach ($files as $file) {
            // 获取前三位作为组标识符
            $groupKey = substr($file, 0, 3);

            // 如果组标识符不存在于结果数组中，则初始化一个新的组
            if (!isset($groupedFiles[$groupKey])) {
                $groupedFiles[$groupKey] = [];
            }

            // 将文件添加到对应的组中
            $groupedFiles[$groupKey][] = $file;
        }

        // 对每个组进行排序
        foreach ($groupedFiles as &$group) {
            usort($group, [$this, 'customSort']);
        }
        unset($group); // 解除引用

        // 对组标识符进行排序
        ksort($groupedFiles);

        return $groupedFiles;
    }

        /**
     * 扫描目录并过滤掉以.开头的文件
     * 
     * @param string $path 目录路径
     * @return array 过滤后的文件列表
     */
    protected function myScandir($path)
    {
        if (!is_dir($path)) {
            return [];
        }

        $files = scandir($path);
        $filteredFiles = [];

        foreach ($files as $file) {
            // 跳过 . 开头的文件和目录
            if ($file[0] === '.') {
                continue;
            }
            $filteredFiles[] = $file;
        }

        return $filteredFiles;
    }


        /**
     * 自定义排序函数
     * 
     * @param string $a 第一个文件名
     * @param string $b 第二个文件名
     * @return int 排序结果
     */
    protected function customSort($a, $b)
    {
        // 提取数字部分进行比较
        $numA = (int)substr($a, 3, 5);
        $numB = (int)substr($b, 3, 5);

        return $numA - $numB;
    }

    function ollamaMk($cueWord)
    {
       

        $ch = curl_init();

        $url = config("ollamaUrl");

        $model = config("model_name");
       

        $headers = [
           
            'Content-Type: application/json'
        ];
        $data = json_encode([
            "model" =>  $model,
            "options" => ["num_ctx" => 32768, "num_predict" => 4096],
            "num_predict" => 4096, // 限制输出长度
            "messages" => [
                [
                    "role" => "system",
                    "content" => ""
                ],
                [
                    "role" => "user",
                    "content" => $cueWord,
                ]
            ],
            "stream" => false,
            "max_tokens" => 512,
            "stop" => ["<string>"],
            "temperature" => 0.7,
            "top_p" => 0.7,
            "top_k" => 50,
            "frequency_penalty" => 0.5,
            "n" => 1,
            "response_format" => ["type" => "json_object"]
        ]);

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

        // 执行请求并获取响应
        $response = curl_exec($ch);


        if (curl_errno($ch)) {
            echo 'Error:' . curl_error($ch);
        } else {
            // 输出响应结果
            //            echo $response;
        }

        // 关闭cURL资源
        curl_close($ch);


        return $response;
    }


}